package com.aic.aicdetactor.analysis;

import android.R.bool;

public class CubicSpline {
	public enum SplineBoundaryCondition
	 {
	        Natural,
	        ParabolicallyTerminated,
	        FirstDerivative,
	        SecondDerivative
	 }
	
	
	public double x[];
	public double y[];
	public double _c0[]=null;
	public double _c1[]=null;
	public double _c2[]=null;
	public double _c3[]=null;
	public double _x[]=null;
	public double numArray[]=null;
	public SplineBoundaryCondition Natural=SplineBoundaryCondition.Natural;
	public SplineBoundaryCondition ParabolicallyTerminated=SplineBoundaryCondition.ParabolicallyTerminated;
	public SplineBoundaryCondition FirstDerivative=SplineBoundaryCondition.FirstDerivative;
	public SplineBoundaryCondition SecondDerivative=SplineBoundaryCondition.SecondDerivative;
	public int xLen=0;
	
	public int DOUBLELEN=8;
	//2016-04-05 liuhg添加
    public static double PT1000Array[] ={803.063,807.033,811.003,814.970,818.937,822.902,826.865,830.828,834.789,838.748,
        842.707,846.664,850.619,854.573,858.526,862.478,866.428,870.377,874.325,878.272,
        882.217,886.161,890.103,894.044,897.985,901.923,905.861,909.798,913.733,917.666,
        921.599,925.531,929.460,933.390,937.317,941.244,945.170,949.094,953.016,956.938,
        960.859,964.779,968.697,972.614,976.529,980.444,984.358,988.270,992.181,996.091,
        1000.000,1003.908,1007.814,1011.720,1015.624,1019.527,1023.429,1027.330,1031.229,1035.128,
        1039.025,1042.921,1046.816,1050.710,1054.603,1058.495,1062.385,1066.274,1070.162,1074.049,
        1077.935,1081.820,1085.703,1089.585,1093.467,1097.347,1101.225,1105.103,1108.980,1112.855,
        1116.729,1120.602,1124.474,1128.345,1132.215,1136.083,1139.950,1143.817,1147.681,1151.545,
        1155.408,1159.270,1163.130,1166.989,1170.847,1174.704,1178.560,1182.414,1186.268,1190.120,
        1193.971,1197.821,1201.670,1205.518,1209.364,1213.210,1217.054,1220.897,1224.739,1228.579,
        1232.419,1236.257,1240.095,1243.931,1247.766,1251.600,1255.432,1259.264,1263.094,1266.923,
        1270.751,1274.578,1278.404,1282.228,1286.052,1289.874,1293.695,1297.515,1301.334,1305.152,
        1308.968,1312.783,1316.597,1320.411,1324.222,1328.033,1331.843,1335.651,1339.458,1343.264,
        1347.069,1350.873,1354.676,1358.477,1362.277,1366.077,1369.875,1373.671,1377.467,1381.262,
        1385.055,1388.847,1392.638,1396.428,1400.217,1404.005,1407.791,1411.576,1415.360,1419.143,
        1422.925,1426.706,1430.485,1434.264,1438.041,1441.817,1445.592,1449.366,1453.138,1456.910,
        1460.680,1464.449,1468.217,1471.984,1475.750,1479.514,1483.277,1487.040,1490.801,1494.561,
        1498.319,1502.077,1505.833,1509.589,1513.343,1517.096,1520.847,1524.598,1528.381,1532.139,
        1535.843,1539.589,1543.334,1547.078,1550.820,1554.562,1558.302,1562.041,1565.779,1569.516,
        1573.251,1576.986,1580.719,1584.451,1588.182,1591.912,1595.641,1599.368,1603.094,1606.820,
        1610.544,1614.267,1617.989,1621.709,1625.429,1629.147,1632.864,1636.580,1640.295,1644.009,
        1647.721,1651.433,1655.143,1658.852,1662.560,1666.267,1669.972,1673.677,1677.380,1681.082,
        1684.783,1688.483,1692.181,1695.879,1699.575,1703.271,1706.965,1710.658,1714.349,1718.040,
        1721.729,1725.418,1729.105,1732.791,1736.475,1740.159,1743.842,1747.523,1751.203,1754.882,
        1758.560,1762.237,1765.912,1769.587,1773.260,1776.932,1780.603,1784.273,1787.941,1791.610,
        1795.275,1798.940,1802.604,1806.267,1809.929,1813.590,1817.249,1820.907,1824.564,1828.220,
        1831.875,1835.529,1839.181,1842.832,1846.483,1850.132,1853.779,1857.426,1861.072,1864.716,
        1868.359,1872.001,1875.642,1879.282,1882.921,1886.558,1890.194,1893.830,1897.463,1901.096,
        1904.728,1908.359,1911.988,1915.616,1919.243,1922.869,1926.494,1930.117,1933.740,1937.361,
        1940.981,1944.600,1948.218,1951.835,1955.450,1959.065,1962.678,1966.290,1969.901,1973.510,
        1977.119,1980.726,1984.333,1987.938,1991.542,1995.145,1998.746,2002.347,2005.946,2009.544,
        2013.141,2016.737,2020.332,2023.925,2027.518,2031.109,2034.699,2038.288,2041.876,2045.463,
        2049.048,2052.632,2056.215,2059.798,2063.378,2066.958,2070.537,2074.114,2077.690,2081.265,
        2084.839,2088.412,2091.984,2095.554,2099.123,2102.692,2106.259,2109.824,2113.389,2116.953,
        2120.515};
  
    //2016-04-05 liuhg添加
    public static double PT100Array[]={18.52,
        18.95,19.38,19.82,20.25,20.68,21.11,21.54,21.97,22.40,22.83, 
        23.25,23.68,24.11,24.54,24.97,25.39,25.82,26.24,26.67,27.10, 
        27.52,27.95,28.37,28.80,29.22,29.64,30.07,30.49,30.91,31.34, 
        31.76,32.18,32.60,33.02,33.44,33.86,34.28,34.70,35.12,35.54,            
        35.96,36.38,36.80,37.22,37.64,38.05,38.47,38.89,39.31,39.72,
        40.14,40.56,40.97,41.39,41.80,42.22,42.63,43.05,43.46,43.88,              
        44.29,44.70,45.12,45.53,45.94,46.36,46.77,47.18,47.59,48.00,
        48.42,48.83,49.24,49.65,50.06,50.47,50.88,51.29,51.70,52.11,
        52.52,52.93,53.34,53.75,54.15,54.56,54.97,55.38,55.79,56.19,                
        56.60,57.01,57.41,57.82,58.23,58.63,59.04,59.44,59.85,60.26,
        60.66,61.07,61.47,61.88,62.28,62.68,63.09,63.49,63.90,64.30,                
        64.70,65.11,65.51,65.91,66.31,66.72,67.12,67.52,67.92,68.33,
        68.73,69.13,69.53,69.93,70.33,70.73,71.13,71.53,71.93,72.33,                
        72.73,73.13,73.53,73.93,74.33,74.73,75.13,75.53,75.93,76.33,
        76.73,77.12,77.52,77.92,78.32,78.72,79.11,79.51,79.91,80.31,                  
        80.70,81.10,81.50,81.89,82.29,82.69,83.08,83.48,83.87,84.27,
        84.67,85.06,85.46,85.85,86.25,86.64,87.04,87.43,87.83,88.22,
        88.62,89.01,89.40,89.80,90.19,90.59,90.98,91.37,91.77,92.16,                 
        92.55,92.95,93.34,93.73,94.12,94.52,94.91,95.30,95.69,96.09,
        96.48,96.87,97.26,97.65,98.04,98.44,98.83,99.22,99.61,100.00,
			100.39,100.78,101.17,101.56,101.95,102.34,102.73,103.12,103.51, 
        103.90,104.29,104.68,105.07,105.46,105.85,106.24,106.63,107.02,107.40,
        107.79,108.18,108.57,108.96,109.35,109.73,110.12,110.51,110.90,111.29,
        111.67,112.06,112.45,112.83,113.22,113.61,114.00,114.38,114.77,115.15,
        115.54,115.93,116.31,116.70,117.08,117.47,117.86,118.24,118.63,119.01,
        119.40,119.78,120.17,120.55,120.94,121.32,121.71,122.09,122.47,122.86,
        123.24,123.63,124.01,124.39,124.78,125.16,125.54,125.93,126.31,126.69, 
        127.08,127.46,127.84,128.22,128.61,128.99,129.37,129.75,130.13,130.52, 
        130.90,131.28,131.66,132.04,132.42,132.80,133.18,133.57,133.95,134.33, 
        134.71,135.09,135.47,135.85,136.23,136.61,136.99,137.37,137.75,138.13, 
        138.51,138.88,139.26,139.64,140.02,140.40,140.78,141.16,141.54,141.91, 
        142.29,142.67,143.05,143.43,143.80,144.18,144.56,144.94,145.31,145.69, 
        146.07,146.44,146.82,147.20,147.57,147.95,148.33,148.70,149.08,149.46, 
        149.83,150.21,150.58,150.96,151.33,151.71,152.08,152.46,152.83,153.21, 
        153.58,153.96,154.33,154.71,155.08,155.46,155.83,156.20,156.58,156.95, 
        157.33,157.70,158.07,158.45,158.82,159.19,159.56,159.94,160.31,160.68, 
        161.05,161.43,161.80,162.17,162.54,162.91,163.29,163.66,164.03,164.40, 
        164.77,165.14,165.51,165.89,166.26,166.63,167.00,167.37,167.74,168.11, 
        168.48,168.85,169.22,169.59,169.96,170.33,170.70,171.07,171.43,171.80, 
        172.17,172.54,172.91,173.28,173.65,174.02,174.38,174.75,175.12,175.49, 
        175.86,176.22,176.59,176.96,177.33,177.69,178.06,178.43,178.79,179.16, 
        179.53,179.89,180.26,180.63,180.99,181.36,181.72,182.09,182.46,182.82, 
        183.19,183.55,183.92,184.28,184.65,185.01,185.38,185.74,186.11,186.47, 
        186.84,187.20,187.56,187.93,188.29,188.66,189.02,189.38,189.75,190.11, 
        190.47,190.84,191.20,191.56,191.92,192.29,192.65,193.01,193.37,193.74,
        194.10,194.46,194.82,195.18,195.55,195.91,196.27,196.63,196.99,197.35, 
        197.71,198.07,198.43,198.79,199.15,199.51,199.87,200.23,200.59,200.95, 
        201.31,201.67,202.03,202.39,202.75,203.11,203.47,203.83,204.19,204.55, 
        204.90,205.26,205.62,205.98,206.34,206.70,207.05,207.41,207.77,208.13,
        208.48,208.84,209.20,209.56,209.91,210.27,210.63,210.98,211.34,211.70,
        212.05,212.41,212.76,213.12,213.48,213.83,214.19,214.54,214.90,215.25,
        215.61,215.96,216.32,216.67,217.03,217.38,217.74,218.09,218.44,218.80, 
        219.15,219.51,219.86,220.21,220.57,220.92,221.27,221.63,221.98,222.33,
        222.68,223.04,223.39,223.74,224.09,224.45,224.80,225.15,225.50,225.85,
        226.21,226.56,226.91,227.26,227.61,227.96,228.31,228.66,229.02,229.37, 
        229.72,230.07,230.42,230.77,231.12,231.47,231.82,232.17,232.52,232.87, 
        233.21,233.56,233.91,234.26,234.61,234.96,235.31,235.66,236.00,236.35, 
        236.70,237.05,237.40,237.74,238.09,238.44,238.79,239.13,239.48,239.83,
	        240.18,240.52,240.87,241.22,241.56,241.91,242.26,242.60,242.95,243.29,		
        243.64,243.99,244.33,244.68,245.02,245.37,245.71,246.06,246.40,246.75, 
        247.09,247.44,247.78,248.13,248.47,248.81,249.16,249.50,249.85,250.19, 
        250.53,250.88,251.22,251.56,251.91,252.25,252.59,252.93,253.28,253.62, 
        253.96,254.30,254.65,254.99,255.33,255.67,256.01,256.35,256.70,257.04, 
        257.38,257.72,258.06,258.40,258.74,259.08,259.42,259.76,260.10,260.44, 
        260.78,261.12,261.46,261.80,262.14,262.48,262.82,263.16,263.50,263.84,
        264.18,264.52,264.86,265.20,265.53,265.87,266.21,266.55,266.89,267.22,
        267.56,267.90,268.24,268.57,268.91,269.25,269.59,269.92,270.26,270.60, 
        270.93,271.27,271.61,271.94,272.28,272.61,272.95,273.29,273.62,273.96,
        274.29,274.63,274.96,275.30,275.63,275.97,276.30,276.64,276.97,277.31, 
        277.64,277.98,278.31,278.64,278.98,279.31,279.64,279.98,280.31,280.64,
        280.98,281.31,281.64,281.98,282.31,282.64,282.97,283.31,283.64,283.97,
        284.30,284.63,284.97,285.30,285.63,285.96,286.29,286.62,286.85,287.29, 
        287.62,287.95,288.28,288.61,288.94,289.27,289.60,289.93,290.26,290.59,
        290.92,291.25,291.58,291.91,292.24,292.56,292.89,293.22,293.55,293.88, 
        294.21,294.54,294.86,295.19,295.52,295.85,296.18,296.50,296.83,297.16,
        297.49,297.81,298.14,298.47,298.80,299.12,299.45,299.78,300.10,300.43,
			300.75,301.08,301.41,301.73,302.06,302.38,302.71,303.03,303.36,303.69, 
        304.01,304.34,304.66,304.98,305.31,305.63,305.96,306.28,306.61,306.93, 
        307.25,307.58,307.90,308.23,308.55,308.87,309.20,309.52,309.84,310.16, 
        310.49,310.81,311.13,311.45,311.78,312.10,312.42,312.74,313.06,313.39,
        313.71,314.03,314.35,314.67,314.99,315.31,315.64,315.96,316.28,316.60, 
        316.92,317.24,317.56,317.88,318.20,318.52,318.84,319.16,319.48,319.80, 
        320.12,320.43,320.75,321.07,321.39,321.71,322.03,322.35,322.67,322.98,
        323.30,323.62,323.94,324.26,324.57,324.89,325.21,325.53,325.84,326.16, 
        326.48,326.79,327.11,327.43,327.74,328.06,328.38,328.69,329.01,329.32,
        329.64,329.96,330.27,330.59,330.90,331.22,332.79};
    
    public final static int Resistance=3300;//2016-04-05 liuhg添加 PT100或PT1000型传感器计算阻值时的阻值常数
	public boolean IsSus()
	{
      if(xLen>2&&_c0!=null&&_c1!=null&&_c2!=null&&_c3!=null&&_x!=null&&numArray!=null)
		  return true;
	  else
		  return false;
	}
	
	public boolean InterpolateNatural(double px[], int pxLen,double py[], int pyLen)
	   {
		   if(pxLen!=pyLen||pxLen<2||_x==null||_c0==null||_c1==null||_c2==null||_c3==null)
			 return false;
	       
		   InterpolateBoundaries(px, py, SecondDerivative, 0.0, SecondDerivative, 0.0);

	       return true;
	   }
	public void InterpolateBoundaries(double px[], double py[], SplineBoundaryCondition leftBoundaryCondition, double leftBoundary, SplineBoundaryCondition rightBoundaryCondition, double rightBoundary)
	   {

		  InterpolateBoundariesInplace(px,py,leftBoundaryCondition, leftBoundary, rightBoundaryCondition, rightBoundary);
		  return;

	   }
	 public void InterpolateBoundariesInplace(double px[], double py[], SplineBoundaryCondition leftBoundaryCondition, double leftBoundary, SplineBoundaryCondition rightBoundaryCondition, double rightBoundary)
	   {
	       InterpolateBoundariesSorted(px, py, leftBoundaryCondition, leftBoundary, rightBoundaryCondition, rightBoundary);
	       return;
	   }
	   
	   public void  InterpolateBoundariesSorted(double x[], double y[], SplineBoundaryCondition leftBoundaryCondition, double leftBoundary, SplineBoundaryCondition rightBoundaryCondition, double rightBoundary)
       {
			  int length =xLen;
           if (((length == 2) && (leftBoundaryCondition == ParabolicallyTerminated)) && (rightBoundaryCondition == ParabolicallyTerminated))
           {
               leftBoundaryCondition = SecondDerivative;
               leftBoundary = 0.0;
               rightBoundaryCondition = SecondDerivative;
               rightBoundary = 0.0;
           }
           if (leftBoundaryCondition == Natural)
           {
               leftBoundaryCondition = SecondDerivative;
               leftBoundary = 0.0;
           }
           if (rightBoundaryCondition == Natural)
           {
               rightBoundaryCondition = SecondDerivative;
               rightBoundary = 0.0;
           }
			
           double a[] = new double[length];
           double b[] = new double[length];
           double c[] = new double[length];
           double d[] = new double[length];

           switch (leftBoundaryCondition)
           {
               case ParabolicallyTerminated:
                   a[0] = 0.0;
                   b[0] = 1.0;
                   c[0] = 1.0;
                   d[0] = (2.0 * (y[1] - y[0])) / (x[1] - x[0]);
                   break;
               
               case FirstDerivative:
                   a[0] = 0.0;
                   b[0] = 1.0;
                   c[0] = 0.0;
                   d[0] = leftBoundary;
                   break;
               
               case SecondDerivative:
                   a[0] = 0.0;
                   b[0] = 2.0;
                   c[0] = 1.0;
                   d[0] = (3.0 * ((y[1] - y[0]) / (x[1] - x[0]))) - ((0.5 * leftBoundary) * (x[1] - x[0]));
                   break;
               
               default:
                 //  throw new NotSupportedException(Resources.InvalidLeftBoundaryCondition);
					;
           }
           for (int i = 1; i < (xLen - 1); i++)
           {
               a[i] = x[i + 1] - x[i];
               b[i] = 2.0 * (x[i + 1] - x[i - 1]);
               c[i] = x[i] - x[i - 1];
               d[i] = (((3.0 * (y[i] - y[i - 1])) / (x[i] - x[i - 1])) * (x[i + 1] - x[i])) + (((3.0 * (y[i + 1] - y[i])) / (x[i + 1] - x[i])) * (x[i] - x[i - 1]));
           }
           switch (rightBoundaryCondition)
           {
               case ParabolicallyTerminated:
                   a[length - 1] = 1.0;
                   b[length - 1] = 1.0;
                   c[length - 1] = 0.0;
                   d[length - 1] = (2.0 * (y[length - 1] - y[length - 2])) / (x[length - 1] - x[length - 2]);
                   break;
               
               case FirstDerivative:
                   a[length - 1] = 0.0;
                   b[length - 1] = 1.0;
                   c[length - 1] = 0.0;
                   d[length - 1] = rightBoundary;
                   break;
               
               case SecondDerivative:
                   a[length - 1] = 1.0;
                   b[length - 1] = 2.0;
                   c[length - 1] = 0.0;
                   d[length - 1] = ((3.0 * (y[length - 1] - y[length - 2])) / (x[length - 1] - x[length - 2])) + ((0.5 * rightBoundary) * (x[length - 1] - x[length - 2]));
                   break;
               
               default:
                 //  throw new NotSupportedException(Resources.InvalidRightBoundaryCondition);
					;
           }

           double firstDerivatives[] = SolveTridiagonal(a, b, c, d);
	
           InterpolateHermiteSorted(x, y, firstDerivatives);
           return;


       }
       public double[] SolveTridiagonal(double a[], double b[], double c[], double d[])
       {
           for (int i = 1; i < xLen; i++)
           {
               double num2 = a[i] / b[i - 1];
               b[i] -= num2 * c[i - 1];
               d[i] -= num2 * d[i - 1];
           }
          //  numArray = new double[xLen];
           numArray[xLen - 1] = d[xLen - 1] / b[xLen - 1];
           for (int j = xLen - 2; j >= 0; j--)
           {
               numArray[j] = (d[j] - (c[j] * numArray[j + 1])) / b[j];
           }
           return numArray;
       }
       
       public void InterpolateHermiteSorted(double x[], double y[], double firstDerivatives[])
       {
		   double numArray1[] = _c0;
           double numArray2[] = _c1;
           double numArray3[] = _c2;
           double numArray4[] = _c3;
           for (int i = 0; i < xLen - 1; i++)
           {
               double num2 = x[i + 1] - x[i];
               double num3 = num2 * num2;
               numArray1[i] = y[i];
               numArray2[i] = firstDerivatives[i];
               numArray3[i] = ((((3.0 * (y[i + 1] - y[i])) / num2) - (2.0 * firstDerivatives[i])) - firstDerivatives[i + 1]) / num2;
               numArray4[i] = ((((2.0 * (y[i] - y[i + 1])) / num2) + firstDerivatives[i]) + firstDerivatives[i + 1]) / num3;
           }
           System.arraycopy(x, 0, _x, 0, xLen);
       }
       
       public double Interpolate(double t)
       {
			if(xLen<2)
//				return 0;//2016-05-26 liuhg修改前原程序
				return -300;//2016-05-26 liuhg修改

           int index = LeftSegmentIndex(t);
           double num2 = t - _x[index];
           return (_c0[index] + (num2 * (_c1[index] + (num2 * (_c2[index] + (num2 * _c3[index]))))));
       }

       public int LeftSegmentIndex(double t)
       {
			int num =InternalBinarySearch( _x, 0, xLen,  t);

           if (num < 0)
           {
               num = ~num - 1;
           }
			;
			num=(num>0?num:0);
			int xz=xLen- 2;
			return num>xz?xz:num;			
				
       //    return Math.Min(Math.Max(num, 0), _x.Length - 2);

       }


     public int InternalBinarySearch(double arr[], int index, int length, double value)
       {
           int num = index;
           int num2 = (index + length) - 1;
           while (num <= num2)
           {
               int num3 = num + ((num2 - num) >> 1);
               int num4 = CompareTo(arr[num3], value);
               if (num4 == 0)
               {
                   return num3;
               }
               if (num4 < 0)
               {
                   num = num3 + 1;
               }
               else
               {
                   num2 = num3 - 1;
               }
           }
           return ~num;
       }


       public int CompareTo(double thisV,double value)
       {
           if (thisV < value)
           {
               return -1;
           }
           if (thisV > value)
           {
               return 1;
           }
           if (thisV != value)
           {
               if (!Double.isNaN(thisV))
               {
                   return 1;
               }
				;
               if (!Double.isNaN(value))
               {
                   return -1;
               }
           }
           return 0;
       }
       
       public boolean malloc(int exLen)
       {
       	  if(exLen<2)
       		  return false;
       	  ;
               demalloc();
       		xLen=exLen;

       		_c0= new double[xLen];
       		_c1= new double[xLen-1];
       		_c2= new double[xLen-1];
       		_c3= new double[xLen-1];
       		_x= new double[xLen];
       		numArray=new double[xLen];
       	return true;
       }
       
       public void demalloc()
       {
       	if(_c0 != null)
       	 {
       	  _c0=null;
       	}
       	;
       	if(_c1 != null)
       	 {
       		 _c1=null;
       	}
       	;
       	if(_c2 != null)
       	{
       	  _c2=null;
       	}
       ;
       	if(_c3 != null)
       	{
       	  _c3=null;
       	}
       ;
       	if(_x != null)
       	{
       	  _x=null;
       	}
       	;
       	if(numArray != null)
       	{
       		numArray=null;
       	}
       }
}
